#!/usr/bin/env bash

# 这是一个简单的模块管理系统，每个模块单独一个文件，文件中至少要有module_init和module_exit两个函数。
# 加载模块时自动运行初始化函数module_init。
# 系统退出时自动运行module_exit，这个函数不会被信号打断。
# module_init中主要用于检测和设置运行环境，module_exit主要用于恢复之前运行环境。

# 模块文件地址的列表。
LOAD_MODULE_PATH_LIST=()
# 记录了当期模块的个数。
LOAD_MODULE_COUNT=0

# 加载模块，参数是模块文件的地址。
module_load()
{
    module_file_path=$1
    if [[ -z ${module_file_path} ]]; then
        error_echo "The module path cannot be empty!"
        return 1
    fi
    if [[ ! -f "${module_file_path}" ]]; then
        error_echo "${module_file_path} does not exist!"
        return 1
    fi
    [[ ${LOAD_MODULE_COUNT} == 0 ]] && debug_echo "Loading modules, wait a moment..."
    debug_echo "Load Module: ${LOAD_MODULE_COUNT}  Path:${module_file_path}"
    # 检查是否重复
    for path in ${LOAD_MODULE_PATH_LIST[@]}; do 
        if [[ "${path}" == "${module_file_path}" ]]; then
            error_echo "The module already exists! ${path}"
            return 1
        fi
    done
    unset module_init
    # 加载模块文件
    source ${module_file_path}
    # 运行初始化函数成功，则判定模块加载成功。
    if module_init; then
        LOAD_MODULE_PATH_LIST+=("${module_file_path}")
        LOAD_MODULE_COUNT=$[${LOAD_MODULE_COUNT}+1]
        return 0
    else
        error_echo "Init error! ${module_file_path}"
        return 1
    fi
}

# 退出所有模块，退出顺序和加载的顺序相反。
modules_exit()
{
    trap '' INT
    debug_echo "A total of ${LOAD_MODULE_COUNT} modules are loaded, waiting for modules to exit..."
    while [[ ${LOAD_MODULE_COUNT} > 0 ]]; do
        LOAD_MODULE_COUNT=$[${LOAD_MODULE_COUNT}-1]
        debug_echo "Exit Module:${LOAD_MODULE_COUNT}  Path:${LOAD_MODULE_PATH_LIST[${LOAD_MODULE_COUNT}]}"
        unset module_exit
        source ${LOAD_MODULE_PATH_LIST[${LOAD_MODULE_COUNT}]}
        if ! module_exit; then
            error_echo ""
            error_echo "Exit error! ${LOAD_MODULE_PATH_LIST[${LOAD_MODULE_COUNT}]}"
            return 1
        fi
    done
    return 0
}